﻿using System;
using System.Collections.Generic;
using System.Text;
using Csla;
using System.Data.Odbc;
using MinaspetroLibrary.Configuracoes;
using System.Data;
using Csla.Data;

namespace MinaspetroLibrary.BoletoPack
{
    [Serializable()]
    public class Boleto: BusinessBase<Boleto>
    {
        #region Control Properties
        [Csla.NotUndoable()]
        private bool _isEmpty = false;

        public bool IsEmpty
        {
            get { return _isEmpty; }
        }
        #endregion

        #region Business Properties and Methods

        private Guid _id = Guid.NewGuid();

        private int _idSeq = 0;
        
        private string _cnpj = string.Empty;
        
        private double _valor = 0;

        private DateTime _data = DateTime.Now;

        private string _numDocumento = string.Empty;

        private string _razaoSocial = string.Empty;
        
        private string _endereco = string.Empty;
        
        private string _bairro = string.Empty;
        
        private string _cep = string.Empty;
        
        private string _cidade = string.Empty;
        
        private string _estado = string.Empty;

        private DateTime _dataGerBoleto = DateTime.Now;
        
        


        [System.ComponentModel.DataObjectField(true, true)]
        public Guid Id
        {
            get
            {
                CanReadProperty("Id", true);
                return _id;
            }
            set
            {
                CanWriteProperty("Id", true);
                if (_id != value)
                {
                    _id = value;
                    PropertyHasChanged("Id");
                }
            }
        }

        public int IdSeq
        {
            get
            {
                CanReadProperty("IdSeq", true);
                return _idSeq;
            }
        }

        public string Cnpj
        {
            get
            {
                CanReadProperty("Cnpj", true);
                return _cnpj;
            }
            set
            {
                CanWriteProperty("Cnpj", true);
                if (value == null) value = string.Empty;
                if (!_cnpj.Equals(value))
                {
                    _cnpj = value;
                    PropertyHasChanged("Cnpj");
                }
            }
        }

        public double Valor
        {
            get
            {
                CanReadProperty("Valor", true);
                return _valor;
            }
            set
            {
                CanWriteProperty("Valor", true);
                if (_valor != value)
                {
                    _valor = value;
                    PropertyHasChanged("Valor");
                }
            }
        }

        public DateTime Data
        {
            get
            {
                CanReadProperty("Data", true);
                return _data;
            }
            set
            {
                CanWriteProperty("Data", true);
                if (value == null) value = DateTime.Now;
                if (!_data.Equals(value))
                {
                    _data = value;
                    PropertyHasChanged("Data");
                }
            }
        }

        public string DataShortString
        {
            get
            {
                CanReadProperty("Data", true);
                return _data.ToString("dd/MM/yyyy");
            }
        }

        public string DataFullString
        {
            get
            {
                CanReadProperty("Data", true);
                return _data.ToString("dd/MM/yyyy HH:mm");
            }
        }


        public string NumDocumento
        {
            get
            {
                CanReadProperty("NumDocumento", true);
                return _numDocumento;
            }
            set
            {
                CanWriteProperty("NumDocumento", true);
                if (value == null) value = string.Empty;
                if (!_numDocumento.Equals(value))
                {
                    _numDocumento = value;
                    PropertyHasChanged("NumDocumento");
                }
            }
        }

        public string RazaoSocial
        {
            get
            {
                CanReadProperty("RazaoSocial", true);
                return _razaoSocial;
            }
            set
            {
                CanWriteProperty("RazaoSocial", true);
                if (value == null) value = string.Empty;
                if (!_razaoSocial.Equals(value))
                {
                    _razaoSocial = value;
                    PropertyHasChanged("RazaoSocial");
                }
            }
        }

        public string Endereco
        {
            get
            {
                CanReadProperty("Endereco", true);
                return _endereco;
            }
            set
            {
                CanWriteProperty("Endereco", true);
                if (value == null) value = string.Empty;
                if (!_endereco.Equals(value))
                {
                    _endereco = value;
                    PropertyHasChanged("Endereco");
                }
            }
        }

        public string Bairro
        {
            get
            {
                CanReadProperty("Bairro", true);
                return _bairro;
            }
            set
            {
                CanWriteProperty("Bairro", true);
                if (value == null) value = string.Empty;
                if (!_bairro.Equals(value))
                {
                    _bairro = value;
                    PropertyHasChanged("Bairro");
                }
            }
        }

        public string Cep
        {
            get
            {
                CanReadProperty("Cep", true);
                return _cep;
            }
            set
            {
                CanWriteProperty("Cep", true);
                if (value == null) value = string.Empty;
                if (!_cep.Equals(value))
                {
                    _cep = value;
                    PropertyHasChanged("Cep");
                }
            }
        }

        public string Cidade
        {
            get
            {
                CanReadProperty("Cidade", true);
                return _cidade;
            }
            set
            {
                CanWriteProperty("Cidade", true);
                if (value == null) value = string.Empty;
                if (!_cidade.Equals(value))
                {
                    _cidade = value;
                    PropertyHasChanged("Cidade");
                }
            }
        }

        public string Estado
        {
            get
            {
                CanReadProperty("Estado", true);
                return _estado;
            }
            set
            {
                CanWriteProperty("Estado", true);
                if (value == null) value = string.Empty;
                if (!_estado.Equals(value))
                {
                    _estado = value;
                    PropertyHasChanged("Estado");
                }
            }
        }

        public DateTime DataGerBoleto
        {
            get
            {
                CanReadProperty("DataGerBoleto", true);
                return _dataGerBoleto;
            }
            set
            {
                CanWriteProperty("DataGerBoleto", true);
                if (!_dataGerBoleto.Equals(value))
                {
                    _dataGerBoleto = value;
                    PropertyHasChanged("DataGerBoleto");
                }
            }
        }

        protected override object GetIdValue()
        {
            return _id.ToString();
        }

        #endregion //Business Properties and Methods

        #region Validation Rules
        private void AddCustomRules()
        {
            //add custom/non-generated rules here...
        }

        private void AddCommonRules()
        {
        }

        protected override void AddBusinessRules()
        {
            AddCommonRules();
            AddCustomRules();
        }
        #endregion //Validation Rules

        #region Authorization Rules
        protected override void AddAuthorizationRules()
        {
            //TODO: Define authorization rules in Boleto
        }


        public static bool CanGetObject()
        {
            //TODO: Define CanGetObject permission in Boleto
            return true;
            //if (Csla.ApplicationContext.User.IsInRole("BoletoViewGroup"))
            //	return true;
            //return false;
        }

        public static bool CanAddObject()
        {
            //TODO: Define CanAddObject permission in Boleto
            return true;
            //if (Csla.ApplicationContext.User.IsInRole("BoletoAddGroup"))
            //	return true;
            //return false;
        }

        public static bool CanEditObject()
        {
            //TODO: Define CanEditObject permission in Boleto
            return true;
            //if (Csla.ApplicationContext.User.IsInRole("BoletoEditGroup"))
            //	return true;
            //return false;
        }

        public static bool CanDeleteObject()
        {
            //TODO: Define CanDeleteObject permission in Boleto
            return true;
            //if (Csla.ApplicationContext.User.IsInRole("BoletoDeleteGroup"))
            //	return true;
            //return false;
        }
        #endregion //Authorization Rules

        #region Factory Methods
        private Boleto()
        { /* require use of factory method */ }

        public static Boleto NewBoleto()
        {
            if (!CanAddObject())
                throw new System.Security.SecurityException("Usuário não autorizado a adicionar Boleto");
            return DataPortal.Create<Boleto>();
        }


        public static Boleto GetBoleto(Guid id)
        {
            if (!CanGetObject())
                throw new System.Security.SecurityException("Usuário não autorizado a visualizar Boleto");
            return DataPortal.Fetch<Boleto>(new Criteria(id));
        }

        public static Boleto GetBoleto(string numDoc)
        {
            if (!CanGetObject())
                throw new System.Security.SecurityException("Usuário não autorizado a visualizar Boleto");
            return DataPortal.Fetch<Boleto>(new Criteria(string.Empty, numDoc));
        }

        public override Boleto Save()
        {
            if (IsDeleted && !CanDeleteObject())
                throw new System.Security.SecurityException("Usuário não autorizado a remover Boleto");
            else if (IsNew && !CanAddObject())
                throw new System.Security.SecurityException("Usuário não autorizado a adicionar Boleto");
            else if (!CanEditObject())
                throw new System.Security.SecurityException("Usuário não autorizado a atualizar Boleto");

            return base.Save();
        }

        public static void DeleteBoleto(Guid id)
        {
            if (!CanDeleteObject())
                throw new System.Security.SecurityException("Usuário não autorizado a remover Boleto");
            DataPortal.Delete(new Criteria(id));
        }

        #endregion

        #region Data Access

        #region Criteria

        [Serializable()]
        private class Criteria
        {
            public Guid Id = Guid.NewGuid();
            public string Cnpj = string.Empty;
            public string NumDocumento = string.Empty;
            public DateTime DataBol = DateTime.Now;

            public Criteria(Guid Id)
            {
                this.Id = Id;
            }

            public Criteria(string Cnpj)
            {
                this.Cnpj = Cnpj;
            }

            public Criteria(string Cnpj, string NumDocumento)
            {
                this.Cnpj = Cnpj;
                this.NumDocumento = NumDocumento;

            }

            public Criteria(string Cnpj, DateTime DataBol)
            {
                this.Cnpj = Cnpj;
                this.DataBol = DataBol;

            }
        }


        #endregion //Criteria

        #region Data Access - Create
        [RunLocal]
        protected override void DataPortal_Create()
        {
            _isEmpty = false;
            ValidationRules.CheckRules();
        }

        #endregion //Data Access - Create

        #region Data Access - Fetch
        private void DataPortal_Fetch(Criteria criteria)
        {
            using (OdbcConnection cn = new OdbcConnection(ConfigDatabase.MinaspetroConnection))
            {
                cn.Open();
                ExecuteFetch(cn, criteria);
            }
        }

        private void ExecuteFetch(OdbcConnection cn, Criteria criteria)
        {
            using (OdbcCommand cm = cn.CreateCommand())
            {
                cm.CommandType = CommandType.Text;
                cm.CommandText = GetFetchScript(criteria);

                using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
                {
                    FetchObject(dr);
                    ValidationRules.CheckRules();
                    FetchChildren(dr);
                }
            }
        }

        private string GetFetchScript(Criteria criteria)
        {
            string strQuery = "SELECT "
                  + "IdSeq, "
                  + " Id, "
                  + " Cnpj, "
                  + " Valor, "
                  + " Data, "
                  + " NumDocumento, "
                  + " RazaoSocial, "
                  + " Endereco, "
                  + " Bairro, "
                  + " Cep, "
                  + " Cidade, "
                  + " Estado, "
                  + " DataGerBoleto "
                  + " FROM Boletotb "
                  + " WHERE ";
            if (!criteria.NumDocumento.ToString().Equals(string.Empty))
                strQuery += " NumDocumento=\"" + criteria.NumDocumento.ToString() + "\";";
            else if(!criteria.Id.ToString().Equals(string.Empty))
                strQuery += " Id=\"" + criteria.Id.ToString() + "\";";
            else
                strQuery += " 1=1;";

            return strQuery;
        }

        private void FetchObject(SafeDataReader dr)
        {
            _isEmpty = !dr.Read();
            if (_isEmpty) return;
            _idSeq = dr.GetInt32("IdSeq");
            _id = new Guid(dr["Id"].ToString());
            _cnpj = dr.GetString("Cnpj");
            _valor = dr.GetDouble("Valor");
            _data = dr.GetDateTime("Data");
            _numDocumento = dr.GetString("NumDocumento");
            _razaoSocial = dr.GetString("RazaoSocial");
            _endereco = dr.GetString("Endereco");
            _bairro = dr.GetString("Bairro");
            _cep = dr.GetString("Cep");
            _cidade = dr.GetString("Cidade");
            _estado = dr.GetString("Estado");
            _dataGerBoleto = dr.GetDateTime("DataGerBoleto");
            
        }

        private void FetchChildren(SafeDataReader dr)
        {
        }
        #endregion //Data Access - Fetch

        #region Data Access - Insert
        protected override void DataPortal_Insert()
        {
            using (OdbcConnection cn = new OdbcConnection(ConfigDatabase.MinaspetroConnection))
            {
                cn.Open();

                ExecuteInsert(cn);

                //update child object(s)
                UpdateChildren(cn);
            }//using
            MinaspetroLibrary.UsuarioPack.Usuario.UsuarioInSession.AtualizarHitorico("Insert - Boletotb - Id: " + _id.ToString());
        }

        private void ExecuteInsert(OdbcConnection cn)
        {
            using (OdbcCommand cm = cn.CreateCommand())
            {
                cm.CommandType = CommandType.Text;
                cm.CommandText = GetInsertScript();
                cm.ExecuteNonQuery();
            }//using
        }

        private string GetInsertScript()
        {
            return "INSERT INTO Boletotb "
                + "( Id, IdSeq, Cnpj, Valor, Data, NumDocumento, RazaoSocial, Endereco, Bairro, Cep,"  
                + "Cidade, Estado, DataGerBoleto) "
                + " VALUES (\""
                + _id.ToString().Trim().Replace("\"", "\\\"") + "\", \""
                + _idSeq.ToString().Trim().Replace("\"", "\\\"") + "\", \""
                + _cnpj.ToString().Trim().Replace("\"", "\\\"") + "\", \""
                + _valor.ToString().Trim().Replace("\"", "\\\"") + "\", \"" 
                + _data.ToString("yyyy-MM-dd HH:mm:ss") + "\", \"" 
                + _numDocumento.ToString().Trim().Replace("\"", "\\\"") + "\", \"" 
                + _razaoSocial.ToString().Trim().Replace("\"", "\\\"") + "\", \"" 
                + _endereco.ToString().Trim().Replace("\"", "\\\"") + "\", \"" 
                + _bairro.ToString().Trim().Replace("\"", "\\\"") + "\", \"" 
                + _cep.ToString().Trim().Replace("\"", "\\\"") + "\", \"" 
                + _cidade.ToString().Trim().Replace("\"", "\\\"") + "\", \"" 
                + _estado.ToString().Trim().Replace("\"", "\\\"") + "\", \""
                + _dataGerBoleto.ToString("yyyy-MM-dd HH:mm:ss") + "\")";
        }
        #endregion //Data Access - Insert

        #region Data Access - Update
        protected override void DataPortal_Update()
        {
            using (OdbcConnection cn = new OdbcConnection(ConfigDatabase.MinaspetroConnection))
            {
                cn.Open();

                if (base.IsDirty)
                {
                    ExecuteUpdate(cn);
                }

                //update child object(s)
                UpdateChildren(cn);
            }//using
            MinaspetroLibrary.UsuarioPack.Usuario.UsuarioInSession.AtualizarHitorico("Update - Boletotb - Id: " + _id.ToString());
        }

        private void ExecuteUpdate(OdbcConnection cn)
        {
            using (OdbcCommand cm = cn.CreateCommand())
            {
                cm.CommandType = CommandType.Text;
                cm.CommandText = GetUpdateScript();

                if (cm.ExecuteNonQuery() == 0)
                    throw new Exception("Este registro foi editado por outro usuario.");
            }//using
        }

        private string GetUpdateScript()
        {
            return "Update Boletotb set "
                    + "RazaoSocial=\"" + _razaoSocial.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "Cnpj=\"" + _cnpj.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "Valor =\"" + _valor.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "Data =\"" + _data.ToString("yyyy-MM-dd HH:mm:ss") + "\", "
                    + "NumDocumento =\"" + _numDocumento.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "RazaoSocial =\"" + _razaoSocial.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "Endereco =\"" + _endereco.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "Bairro =\"" + _bairro.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "Cep =\"" + _cep.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "Cidade =\"" + _cidade.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "Estado =\"" + _estado.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "DataGerBoleto=\"" + _dataGerBoleto.ToString("yyyy-MM-dd HH:mm:ss") + "\" "
                    + "WHERE Id=\"" + _id.ToString().Trim().Replace("\"", "\\\"") + "\";";
        }

        private void UpdateChildren(OdbcConnection cn)
        {
        }
        #endregion //Data Access - Update

        #region Data Access - Delete
        protected override void DataPortal_DeleteSelf()
        {
            DataPortal_Delete(new Criteria(_id));
        }

        private void DataPortal_Delete(Criteria criteria)
        {
            using (OdbcConnection cn = new OdbcConnection(ConfigDatabase.MinaspetroConnection))
            {
                cn.Open();

                ExecuteDelete(cn, criteria);

            }//using
            MinaspetroLibrary.UsuarioPack.Usuario.UsuarioInSession.AtualizarHitorico("Delete - Boletotb - Id: " + _id.ToString());
        }

        private void ExecuteDelete(OdbcConnection cn, Criteria criteria)
        {
            using (OdbcCommand cm = cn.CreateCommand())
            {
                cm.CommandType = CommandType.Text;
                cm.CommandText = "DELETE from Boletotb WHERE Id=\"" + criteria.Id.ToString() + "\";";

                cm.ExecuteNonQuery();
            }//using
        }
        #endregion //Data Access - Delete


        #endregion //Data Access
    }
}